package com.sky.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.entity.Setmeal;
import com.sky.exception.BaseException;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @author zzw
 * @date 2025/4/29
 * @description 菜品管理服务实现类
 */
@Service
public class DishServiceImpl implements DishService {

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private DishFlavorMapper dishFlavorMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    @Autowired
    private SetmealMapper setmealMapper;

    /**
     * 菜品分页查询
     *
     * @param dishPageQueryDTO 菜品分页查询传输对象
     * @return PageResult<DishVO>
     */
    @Override
    public PageResult<DishVO> page(DishPageQueryDTO dishPageQueryDTO) {
        // 1.设置分页参数
        PageHelper.startPage(dishPageQueryDTO.getPage(), dishPageQueryDTO.getPageSize());

        // 2.执行分页查询
        Page<DishVO> page = dishMapper.page(dishPageQueryDTO);

        // 3.返回封装后的结果
        return new PageResult<>(page.getTotal(), page.getResult());
    }

    /**
     * 修改菜品
     *
     * @param dishDTO 菜品传输对象
     */
    @Override
    @Transactional
    public void updateWithFlavor(DishDTO dishDTO) {
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);

        // 修改菜品基本信息
        dishMapper.update(dish);

        // 2.修改菜品口味信息
        // 2.1 删除该菜品的口味信息
        dishFlavorMapper.deleteByDishId(Collections.singletonList(dishDTO.getId()));
        // 2.2 添加新的口味信息
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (flavors != null && !flavors.isEmpty()) {
            flavors.forEach(dishFlavor -> dishFlavor.setDishId(dishDTO.getId()));
            dishFlavorMapper.insertBatch(flavors);
        }
    }

    /**
     * 根据id查询菜品信息和口味信息
     *
     * @param id 菜品id
     * @return DishVO
     */
    @Override
    public DishVO getByIdWithFlavor(Long id) {
        // 1.根据id查询菜品数据
        Dish dish = dishMapper.getById(id);
        if (dish == null) {
            throw new BaseException("菜品不存在");
        }

        // 2.根据菜品id查询菜品口味数据
        List<DishFlavor> flavors = dishFlavorMapper.getByDishId(id);

        // 3.将查询到的数据封装到dishVO中
        DishVO dishVO = new DishVO();
        BeanUtils.copyProperties(dish, dishVO);
        dishVO.setFlavors(flavors);

        return dishVO;
    }

    /**
     * 启用或禁用菜品
     *
     * @param status 状态
     * @param id     菜品id
     */
    @Override
    public void status(Integer status, Long id) {
        // 1.根据id查询菜品信息
        Dish dish = dishMapper.getById(id);
        if (dish == null) {
            throw new BaseException("菜品不存在");
        }

        // 2.判断菜品是否关联了套餐
        List<Long> setmealIds = setmealDishMapper.getByDishId(id);
        if (setmealIds != null && !setmealIds.isEmpty()) {
            // 2.1 如果关联了套餐，判断套餐是否是启售状态
            List<Setmeal> setmeals = setmealMapper.getByStatusAndIds(StatusConstant.ENABLE, setmealIds);
            if (setmeals != null && !setmeals.isEmpty()) {
                throw new BaseException("该菜品关联了启售套餐，不能停售");
            }
        }

        // 3.修改菜品状态
        dishMapper.update(dish);
    }

    /**
     * 批量删除菜品
     *
     * @param ids 菜品id数组
     */
    @Override
    @Transactional
    public void deleteBatch(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new DeletionNotAllowedException("请选择要删除的菜品后再删除");
        }
        // 1.判断菜品是否在售中
        for (Long id : ids) {
            Dish dish = dishMapper.getById(id);
            if (Objects.equals(dish.getStatus(), StatusConstant.ENABLE)) {
                throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
            }
        }

        // 2.判断菜品是否关联了套餐
        List<Long> setmealIds = setmealDishMapper.getSetmealIdsByDishId(ids);
        if (setmealIds != null && !setmealIds.isEmpty()) {
            throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
        }

        // 3.删除菜品口味信息
        dishFlavorMapper.deleteByDishId(ids);

        // 4.删除菜品信息
        dishMapper.deleteBatch(ids);
    }

    /**
     * 新增菜品
     *
     * @param dishDTO 新增菜品DTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveWithFlavor(DishDTO dishDTO) {
        // 1.创建菜品对象
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);

        // 2.插入菜品数据
        dishMapper.insert(dish);

        // 3.创建菜品口味对象
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (flavors != null && !flavors.isEmpty()) {
            flavors.forEach(dishFlavor -> dishFlavor.setDishId(dish.getId()));
            // 4.插入菜品口味数据
            dishFlavorMapper.insertBatch(flavors);
        }
    }

    /**
     * @param categoryId 菜品分类id
     * @param name       菜品名称
     * @return List<Dish>
     */
    @Override
    public List<Dish> getByCategoryIdOrName(Long categoryId, String name) {
        if (categoryId != null) {
            return dishMapper.getByCategoryId(categoryId);
        } else if (name != null) {
            return dishMapper.getByName(name);
        } else {
            //TODO 此处用不到
            return dishMapper.getAll();
        }
    }




    /**
     * 获取指定分类下的菜品列表
     *
     * @param categoryId 分类id
     * @return List<DishVO>
     */
    @Override
    public List<DishVO> listDishWithFlavors(Long categoryId) {
        List<DishVO> dishVOList = new ArrayList<>();

        // 1. 根据分类id查询菜品列表
        List<Dish> dishList = dishMapper.getByCategoryId(categoryId);
        if (ObjectUtil.isNotEmpty(dishList)) {
            dishList.forEach(dish -> {
                DishVO dishVO = new DishVO();
                BeanUtils.copyProperties(dish, dishVO);

                // 2. 根据菜品id查询菜品口味列表
                List<DishFlavor> dishFlavorList = dishFlavorMapper.getByDishId(dish.getId());
                dishVO.setFlavors(dishFlavorList);

                dishVOList.add(dishVO);
            });
        }
        return dishVOList;
    }

}
